package org.gdstash.ui;

import org.gdstash.db.DBItem;
import org.gdstash.db.DBStashItem;
import org.gdstash.db.SelectionCriteria;
import org.gdstash.item.GDItem;
import org.gdstash.ui.select.ItemSelectionPane;
import org.gdstash.ui.table.GDItemCollectionSorter;
import org.gdstash.ui.table.GDItemCollectionTableModel;
import org.gdstash.ui.table.GDItemInfo;
import org.gdstash.ui.util.AdjustablePanel;
import org.gdstash.util.GDImagePool;
import org.gdstash.util.GDMsgFormatter;
import org.gdstash.util.GDMsgLogger;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class GDCollectionPane extends AdjustablePanel {
    private GDStashFrame frame;
    private List<GDItemInfo> data;
    private List<GDItem> itemsAll;
    private List<GDItem> itemsFound;
    private GDItemCollectionTableModel model;
    private JTable table;
    private JPanel pnlInfo;
    private JLabel lblCountSC;
    private JTextField tfCountSC;
    private JTextField tfPercSC;
    private JLabel lblCountHC;
    private JTextField tfCountHC;
    private JTextField tfPercHC;
    private int countAll;
    private int countSC;
    private int countHC;
    private float ratioSC;
    private float ratioHC;
    private JButton btnSearch;
    private JButton btnClear;
    private JButton btnHelp;
    private ItemSelectionPane pnlSelect;
    private JButton btnFilterAll;
    private JButton btnFilterFound;
    private JButton btnFilterMiss;

    public GDCollectionPane(final GDStashFrame frame) {
        this.frame = frame;
        this.init();
    }

    @Override
    public void adjustUI() {
        Font fntLabel = UIManager.getDefaults().getFont("Label.font");
        Font fntText = UIManager.getDefaults().getFont("TextField.font");
        if (fntText == null) {
            fntText = fntLabel;
        }
        Font fntBorder = UIManager.getDefaults().getFont("TitledBorder.font");
        if (fntBorder == null) {
            fntBorder = fntLabel;
        }
        Font fntButton = UIManager.getDefaults().getFont("Button.font");
        if (fntButton == null) {
            fntButton = fntLabel;
        }
        Font fntTable = UIManager.getDefaults().getFont("TableHeader.font");
        if (fntTable == null) {
            fntTable = fntLabel;
        }
        fntLabel = fntLabel.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        fntText = fntText.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        fntBorder = fntBorder.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        fntButton = fntButton.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        fntTable = fntTable.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        if (this.btnSearch == null) {
            (this.btnSearch = new JButton()).addActionListener(new SearchItemsListener());
        }
        this.btnSearch.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_SEARCH"));
        this.btnSearch.setIcon(GDImagePool.iconBtnSearch24);
        this.btnSearch.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnSearch, "MNC_SEARCH");
        if (this.btnClear == null) {
            (this.btnClear = new JButton()).addActionListener(new ClearActionListener());
        }
        this.btnClear.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_CLEAR"));
        this.btnClear.setIcon(GDImagePool.iconItemDelete24);
        this.btnClear.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnClear, "MNC_CLEAR");
        if (this.btnHelp == null) {
            (this.btnHelp = new JButton()).addActionListener(new GDHelpActionListener("06_collection.html"));
        }
        this.btnHelp.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_HELP"));
        this.btnHelp.setIcon(GDImagePool.iconBtnQuestion24);
        this.btnHelp.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnHelp, "MNC_HELP");
        if (this.btnFilterAll == null) {
            (this.btnFilterAll = new JButton()).addActionListener(new SelectAllListener());
        }
        this.btnFilterAll.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_FILTER_ALL"));
        this.btnFilterAll.setIcon(GDImagePool.iconCollectAll24);
        this.btnFilterAll.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnFilterAll, "MNC_FILTER_ALL");
        if (this.btnFilterFound == null) {
            (this.btnFilterFound = new JButton()).addActionListener(new SelectFoundListener());
        }
        this.btnFilterFound.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_FILTER_FOUND"));
        this.btnFilterFound.setIcon(GDImagePool.iconCollectFound24);
        this.btnFilterFound.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnFilterFound, "MNC_FILTER_FOUND");
        if (this.btnFilterMiss == null) {
            (this.btnFilterMiss = new JButton()).addActionListener(new SelectMissingListener());
        }
        this.btnFilterMiss.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "BTN_FILTER_MISS"));
        this.btnFilterMiss.setIcon(GDImagePool.iconCollectMiss24);
        this.btnFilterMiss.setFont(fntButton);
        GDStashFrame.setMnemonic(this.btnFilterMiss, "MNC_FILTER_MISS");
        if (this.table == null) {
            this.table = new JTable();
            final GDItemCollectionSorter sorter = new GDItemCollectionSorter();
            this.table.setRowSorter((RowSorter<? extends TableModel>) sorter);
            this.table.getTableHeader().addMouseListener(new SortListener());
            this.setItems(null);
        }
        this.table.getTableHeader().setFont(fntTable);
        this.table.setFont(fntLabel);
        int height = -1;
        if (this.data != null) {
            for (final GDItemInfo info : this.data) {
                final BufferedImage img = info.gdItem.getImage();
                if (img != null && img.getHeight() > height) {
                    height = img.getHeight();
                }
            }
        }
        if (height == -1) {
            height = 12;
        }
        height = height * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
        this.table.setRowHeight(height);
        final GDItemCollectionTableModel model = (GDItemCollectionTableModel) this.table.getModel();
        model.adjustUI();
        this.updateTableColumns();
        if (this.lblCountSC == null) {
            this.lblCountSC = new JLabel();
        }
        this.lblCountSC.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "TXT_SOFTCORE"));
        if (this.tfCountSC == null) {
            (this.tfCountSC = new JTextField()).setEditable(false);
            this.tfCountSC.setColumns(9);
        }
        final Object[] argcntSC = {this.countSC, this.countAll};
        this.tfCountSC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_COUNT", argcntSC));
        if (this.tfPercSC == null) {
            (this.tfPercSC = new JTextField()).setEditable(false);
        }
        final Object[] argpctSC = {this.ratioSC};
        this.tfPercSC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_PERCENT", argpctSC));
        if (this.lblCountHC == null) {
            this.lblCountHC = new JLabel();
        }
        this.lblCountHC.setText(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "TXT_HARDCORE"));
        if (this.tfCountHC == null) {
            (this.tfCountHC = new JTextField()).setEditable(false);
        }
        final Object[] argcntHC = {this.countSC, this.countAll};
        this.tfCountHC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_COUNT", argcntHC));
        if (this.tfPercHC == null) {
            (this.tfPercHC = new JTextField()).setEditable(false);
        }
        final Object[] argpctHC = {this.ratioSC};
        this.tfPercHC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_PERCENT", argpctHC));
        if (this.pnlSelect == null) {
            this.pnlSelect = new ItemSelectionPane(GDTabbedSearchDialog.Mode.SEARCH);
        } else {
            this.pnlSelect.adjustUI();
        }
        final Border lowered = BorderFactory.createEtchedBorder(1);
        final Border raised = BorderFactory.createEtchedBorder(0);
        final Border compound = BorderFactory.createCompoundBorder(raised, lowered);
        final TitledBorder title = BorderFactory.createTitledBorder(compound, GDMsgFormatter.getString(GDMsgFormatter.rbUI, "TXT_COLL_OVERVIEW"));
        title.setTitleFont(fntBorder);
        if (this.pnlInfo == null) {
            this.buildInfoPanel();
        }
        this.pnlInfo.setBorder(title);
    }

    public void refresh() {
        if (this.table != null) {
            final GDItemCollectionTableModel model = (GDItemCollectionTableModel) this.table.getModel();
            model.setData(null);
        }
    }

    private void init() {
        this.countAll = 0;
        this.countSC = 0;
        this.countHC = 0;
        this.ratioSC = 0.0f;
        this.ratioHC = 0.0f;
        this.adjustUI();
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        final JPanel pnlMain = this.buildMainPanel();
        final JScrollPane scroll = new JScrollPane(pnlMain);
        scroll.getVerticalScrollBar().setUnitIncrement(100);
        scroll.getVerticalScrollBar().putClientProperty("JScrollBar.fastWheelScrolling", true);
        scroll.setWheelScrollingEnabled(true);
        layout = new GroupLayout(this);
        this.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(scroll));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(scroll));
        layout.setVerticalGroup(vGroup);
    }

    private JPanel buildMainPanel() {
        final JPanel panel = new JPanel();
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        final JPanel pnlSearch = this.buildSearchPanel();
        final JPanel pnlTable = this.buildTablePanel();
        this.setItems(this.data);
        layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(pnlSearch)).addGroup(layout.createParallelGroup().addComponent(pnlTable));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(pnlSearch).addComponent(pnlTable));
        layout.setVerticalGroup(vGroup);
        return panel;
    }

    private JPanel buildButtonPanel() {
        final BorderLayout layout = new BorderLayout();
        final JPanel panel = new JPanel();
        panel.setLayout(layout);
        panel.add(this.btnSearch, "Center");
        panel.add(this.btnClear, "West");
        panel.add(this.btnHelp, "East");
        return panel;
    }

    private JPanel buildSearchPanel() {
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        final JPanel pnlButton = this.buildButtonPanel();
        final JPanel panel = new JPanel();
        layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(false);
        layout.setAutoCreateContainerGaps(false);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(pnlButton).addComponent(this.pnlSelect).addComponent(this.pnlInfo));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(pnlButton)).addGroup(layout.createParallelGroup().addComponent(this.pnlSelect)).addGroup(layout.createParallelGroup().addComponent(this.pnlInfo));
        layout.setVerticalGroup(vGroup);
        layout.linkSize(0, pnlButton, this.pnlSelect);
        layout.linkSize(0, pnlButton, this.pnlInfo);
        return panel;
    }

    private JPanel buildTablePanel() {
        final JPanel panel = new JPanel();
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        final JPanel pnlFilter = this.buildFilterPanel();
        final JScrollPane scrTable = new JScrollPane(this.table);
        layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(scrTable).addComponent(pnlFilter));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(scrTable)).addGroup(layout.createParallelGroup().addComponent(pnlFilter));
        layout.setVerticalGroup(vGroup);
        return panel;
    }

    private void buildInfoPanel() {
        this.pnlInfo = new JPanel();
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        layout = new GroupLayout(this.pnlInfo);
        this.pnlInfo.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(this.lblCountSC).addComponent(this.lblCountHC)).addGroup(layout.createParallelGroup().addComponent(this.tfCountSC).addComponent(this.tfCountHC)).addGroup(layout.createParallelGroup().addComponent(this.tfPercSC).addComponent(this.tfPercHC));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(this.lblCountSC).addComponent(this.tfCountSC).addComponent(this.tfPercSC)).addGroup(layout.createParallelGroup().addComponent(this.lblCountHC).addComponent(this.tfCountHC).addComponent(this.tfPercHC));
        layout.setVerticalGroup(vGroup);
        layout.linkSize(1, this.lblCountSC, this.tfCountSC);
        layout.linkSize(1, this.lblCountSC, this.tfPercSC);
        layout.linkSize(1, this.lblCountSC, this.lblCountHC);
        layout.linkSize(1, this.lblCountSC, this.tfCountHC);
        layout.linkSize(1, this.lblCountSC, this.tfPercHC);
        layout.linkSize(0, this.lblCountSC, this.lblCountHC);
        layout.linkSize(0, this.tfCountSC, this.tfPercSC);
        layout.linkSize(0, this.tfCountSC, this.tfCountHC);
        layout.linkSize(0, this.tfCountSC, this.tfPercHC);
    }

    private JPanel buildFilterPanel() {
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        final JPanel panel = new JPanel();
        layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(this.btnFilterMiss)).addGroup(layout.createParallelGroup().addComponent(this.btnFilterFound)).addGroup(layout.createParallelGroup().addComponent(this.btnFilterAll));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(this.btnFilterMiss).addComponent(this.btnFilterFound).addComponent(this.btnFilterAll));
        layout.setVerticalGroup(vGroup);
        layout.linkSize(0, this.btnFilterMiss, this.btnFilterFound);
        layout.linkSize(0, this.btnFilterMiss, this.btnFilterAll);
        layout.linkSize(1, this.btnFilterMiss, this.btnFilterFound);
        layout.linkSize(1, this.btnFilterMiss, this.btnFilterAll);
        return panel;
    }

    public void updateConfig() {
        if (this.pnlSelect != null) {
            this.pnlSelect.updateConfig();
        }
    }

    private void search() {
        this.itemsAll = new LinkedList<GDItem>();
        final List<String> itemIDs = new LinkedList<String>();
        final SelectionCriteria criteria = new SelectionCriteria();
        this.pnlSelect.addCriteria(criteria);
        criteria.noEnemyOnly = true;
        if ((criteria.itemIDs == null || criteria.itemIDs.isEmpty()) && (criteria.itemClass == null || criteria.itemClass.isEmpty())) {
            final GDDialog dialog = new GDDialog(GDMsgFormatter.getString(GDMsgFormatter.rbUI, "ERR_SEL_ITEM_TYPE"), 4, this.frame, GDMsgFormatter.getString(GDMsgFormatter.rbUI, "ERROR"), true);
            dialog.setVisible(true);
            return;
        }
        final List<DBItem> dbItems = DBItem.getByCriteria(criteria);
        for (final DBItem dbi : dbItems) {
            final GDItem item = new GDItem(dbi);
            this.itemsAll.add(item);
            if (dbi == null) {
                itemIDs.add(null);
            } else {
                itemIDs.add(dbi.getItemID());
            }
        }
        Collections.<GDItem>sort(this.itemsAll);
        this.itemsFound = DBStashItem.getGDItemsByItemIDs(itemIDs);
        this.setItems(this.data = GDItemInfo.buildItemInfo(this.itemsAll, this.itemsFound));
        GDMsgLogger.showLog(this, GDMsgFormatter.getString(GDMsgFormatter.rbMsg, "ERR_SEARCH"));
    }

    private void updateTableColumns() {
        this.table.getColumnModel().getColumn(1).setCellRenderer(new GDItemTableCellRenderer());
        this.table.getColumnModel().getColumn(2).setCellRenderer(new GDItemTableCellRenderer());
        int scale = 100;
        int size = 12;
        if (GDStashFrame.iniConfig != null) {
            scale = GDStashFrame.iniConfig.sectUI.graphicScale;
            size = GDStashFrame.iniConfig.sectUI.fontSize;
        }
        this.table.getColumnModel().getColumn(0).setPreferredWidth(100 * scale / 100);
        this.table.getColumnModel().getColumn(1).setPreferredWidth(42 * size);
        this.table.getColumnModel().getColumn(2).setPreferredWidth(8 * size);
        this.table.getColumnModel().getColumn(3).setPreferredWidth(3 * size);
        this.table.getColumnModel().getColumn(4).setPreferredWidth(3 * size);
    }

    public void setItems(final List<GDItemInfo> list) {
        this.data = list;
        if (this.data != null) {
            Collections.<GDItemInfo>sort(this.data);
        }
        int height = -1;
        this.countAll = 0;
        this.countSC = 0;
        this.countHC = 0;
        this.ratioSC = 0.0f;
        this.ratioHC = 0.0f;
        if (this.data != null) {
            for (final GDItemInfo info : this.data) {
                if (info == null) {
                    continue;
                }
                final BufferedImage img = info.gdItem.getImage();
                if (img != null && img.getHeight() > height) {
                    height = img.getHeight();
                }
                ++this.countAll;
                if (info.scCount != 0) {
                    ++this.countSC;
                }
                if (info.hcCount == 0) {
                    continue;
                }
                ++this.countHC;
            }
        }
        if (height == -1) {
            height = 12;
        }
        if (this.countAll > 0) {
            this.ratioSC = this.countSC / (float) this.countAll * 100.0f;
        }
        if (this.countAll > 0) {
            this.ratioHC = this.countHC / (float) this.countAll * 100.0f;
        }
        if (this.tfCountSC != null) {
            final Object[] argcntSC = {this.countSC, this.countAll};
            this.tfCountSC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_COUNT", argcntSC));
        }
        if (this.tfPercSC != null) {
            final Object[] argpctSC = {this.ratioSC};
            this.tfPercSC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_PERCENT", argpctSC));
        }
        if (this.tfCountHC != null) {
            final Object[] argcntHC = {this.countHC, this.countAll};
            this.tfCountHC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_COUNT", argcntHC));
        }
        if (this.tfPercHC != null) {
            final Object[] argpctHC = {this.ratioHC};
            this.tfPercHC.setText(GDMsgFormatter.format(GDMsgFormatter.rbUI, "TXT_ITEM_PERCENT", argpctHC));
        }
        this.model = new GDItemCollectionTableModel(this.data);
        this.table.setModel(this.model);
        this.table.setSelectionMode(0);
        this.table.getSelectionModel().addListSelectionListener(this.table);
        final GDItemCollectionSorter sorter = new GDItemCollectionSorter(this.model);
        this.table.setRowSorter((RowSorter<? extends TableModel>) sorter);
        this.updateTableColumns();
        final Rectangle rect = this.table.getVisibleRect();
        rect.setLocation(0, 0);
        this.table.scrollRectToVisible(rect);
        if (height != -1) {
            height = height * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
            this.table.setRowHeight(height);
        }
    }

    private static class GDItemTableCellRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int col) {
            if (col == 0) {
                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
            }
            final JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
            final GDItemCollectionTableModel model = (GDItemCollectionTableModel) table.getModel();
            label.setForeground(model.getCellTextColor(row, col));
            label.setBackground(model.getCellBackgroundColor(row, col));
            return label;
        }
    }

    private class SearchItemsListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            GDCollectionPane.this.setCursor(Cursor.getPredefinedCursor(3));
            GDCollectionPane.this.search();
            GDCollectionPane.this.setCursor(Cursor.getDefaultCursor());
        }
    }

    private class ClearActionListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            GDCollectionPane.this.pnlSelect.clear();
        }
    }

    private class SelectFoundListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            GDCollectionPane.this.model.filter(2);
        }
    }

    private class SelectMissingListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            GDCollectionPane.this.model.filter(3);
        }
    }

    private class SelectAllListener implements ActionListener {
        @Override
        public void actionPerformed(final ActionEvent e) {
            GDCollectionPane.this.model.filter(1);
        }
    }

    private class SortListener extends MouseAdapter {
        @Override
        public void mouseClicked(final MouseEvent ev) {
            final int idx = GDCollectionPane.this.table.getColumnModel().getColumnIndexAtX(ev.getX());
            final GDItemCollectionSorter sorter = (GDItemCollectionSorter) GDCollectionPane.this.table.getRowSorter();
            sorter.sort();
        }
    }
}
